home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / glibc108.zip / glibc108 / sysdeps / mach / hurd / __brk.c < prev    next >
C/C++ Source or Header  |  1994-05-31  |  4KB  |  130 lines

  1. /* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
  2. This file is part of the GNU C Library.
  3.  
  4. The GNU C Library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Library General Public License as
  6. published by the Free Software Foundation; either version 2 of the
  7. License, or (at your option) any later version.
  8.  
  9. The GNU C Library is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  12. Library General Public License for more details.
  13.  
  14. You should have received a copy of the GNU Library General Public
  15. License along with the GNU C Library; see the file COPYING.LIB.  If
  16. not, write to the Free Software Foundation, Inc., 675 Mass Ave,
  17. Cambridge, MA 02139, USA.  */
  18.  
  19. #include <ansidecl.h>
  20. #include <errno.h>
  21. #include <hurd.h>
  22. #include <hurd/resource.h>
  23. #include <cthreads.h>        /* For `struct mutex'.  */
  24. #include <gnu-stabs.h>
  25.  
  26.  
  27. /* Initial maximum size of the data segment (32MB, which is arbitrary).  */
  28. #define    DATA_SIZE    (32 * 1024 * 1024)
  29.  
  30.  
  31. /* Up to the page including this address is allocated from the kernel.
  32.    This address is the data resource limit.  */
  33. vm_address_t _hurd_data_end;
  34.  
  35. /* Up to this address is actually available to the user.
  36.    Pages beyond the one containing this address allow no access.  */
  37. vm_address_t _hurd_brk;
  38.  
  39. struct mutex _hurd_brk_lock;
  40.  
  41. extern int __data_start, _end;
  42.  
  43.  
  44. /* Set the end of the process's data space to INADDR.
  45.    Return 0 if successful, -1 if not.  */
  46. int
  47. DEFUN(__brk, (inaddr), PTR inaddr)
  48. {
  49.   int ret;
  50.   HURD_CRITICAL_BEGIN;
  51.   __mutex_lock (&_hurd_brk_lock);
  52.   ret = _hurd_set_brk ((vm_address_t) inaddr);
  53.   __mutex_unlock (&_hurd_brk_lock);
  54.   HURD_CRITICAL_END;
  55.   return ret;
  56. }
  57.  
  58. int
  59. _hurd_set_brk (vm_address_t addr)
  60. {
  61.   error_t err;
  62.   vm_address_t pagend = round_page (addr);
  63.   vm_address_t pagebrk = round_page (_hurd_brk);
  64.   long int rlimit;
  65.  
  66.   if (pagend <= pagebrk)
  67.     {
  68.       if (pagend < pagebrk)
  69.     /* Make that memory inaccessible.  */
  70.     __vm_protect (__mach_task_self (), pagend, pagebrk - pagend,
  71.               0, VM_PROT_NONE);
  72.       _hurd_brk = addr;
  73.       return 0;
  74.     }
  75.  
  76.   __mutex_lock (&_hurd_rlimit_lock);
  77.   rlimit = _hurd_rlimits[RLIMIT_DATA].rlim_cur;
  78.   __mutex_unlock (&_hurd_rlimit_lock);
  79.  
  80.   if (addr - (vm_address_t) &__data_start > rlimit)
  81.     {
  82.       /* Need to increase the resource limit.  */
  83.       errno = ENOMEM;
  84.       return -1;
  85.     }
  86.  
  87.   /* Make the memory accessible.  */
  88.   if (err = __vm_protect (__mach_task_self (), pagebrk, pagend - pagebrk,
  89.               0, VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE))
  90.     {
  91.       errno = err;
  92.       return -1;
  93.     }
  94.  
  95.   _hurd_brk = addr;
  96.   return 0;
  97. }
  98.  
  99. static void
  100. init_brk (void)
  101. {
  102.   vm_address_t pagend;
  103.  
  104.   __mutex_init (&_hurd_brk_lock);
  105.  
  106.   /* If _hurd_brk is already set, don't change it.  The assumption is that
  107.      it was set in a previous run before something like Emacs's unexec was
  108.      called and dumped all the data up to the break at that point.  */
  109.   if (_hurd_brk == 0)
  110.     _hurd_brk = (vm_address_t) &_end;
  111.  
  112.   pagend = round_page (_hurd_brk);
  113.  
  114.   _hurd_data_end = (vm_address_t) &__data_start + DATA_SIZE;
  115.  
  116.   if (pagend < _hurd_data_end)
  117.     {
  118.       /* We use vm_map to allocate and change permissions atomically.  */
  119.       if (__vm_map (__mach_task_self (), &pagend, _hurd_data_end - pagend,
  120.             0, 0, MACH_PORT_NULL, 0, 0,
  121.             0, VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE,
  122.             VM_INHERIT_COPY))
  123.     /* Couldn't allocate the memory.  The break will be very short.  */
  124.     _hurd_data_end = pagend;
  125.     }
  126.  
  127.   (void) &init_brk;        /* Avoid ``defined but not used'' warning.  */
  128. }
  129. text_set_element (_hurd_preinit_hook, init_brk);
  130.